***************************************************************************
* 	Replication code for:
* 	When Elections Wait: Understanding the Conditions of Election 
* 	Postponement During the COVID-19 Pandemic
* 	Seonghui Lee | Political Research Quarterly (2024)
***************************************************************************

use "repDataElecPostponeExtended.dta", clear
drop if originallypostponed==1		
/* : to analyze initial decisions/incidents only; originallypostponed = 1 indicates repetitive cases (i.e., an election that is once postponed, but not held on the rescheduled date thus requires another decision, becomes a new entry), which will be used for robustness tests (Table A3) */
	
tsset cnum timevar

*=============================
*	Figure 1 pandemic trends
*============================= 

sort timevar

tsline new_cases_smoothed if code3=="OWID_WRL"&timevar>21945&timevar<22677, tlabel(21945(120)22677, format(%tdMon_CCYY)) xtitle("") ylabel(0 "0" 1000000 "1M" 2000000 "2M" 3000000 "3M" 4000000 "4M") ytitle("New Cases, World (Smoothed)") name(g1, replace)

tsline new_deaths_smoothed if code3=="OWID_WRL"&timevar>21945&timevar<22677, tlabel(21945(120)22677, format(%tdMon_CCYY)) xtitle("") ylabel(0 "0" 5000 "5k" 10000 "10k" 15000 "15k") ytitle("New Deaths, World (Smoothed)") name(g2, replace)

tsline  biweeklycasegrowth if code3=="OWID_WRL"&timevar>21945&timevar<22677, tlabel(21945(120)22677, format(%tdMon_CCYY)) xtitle("") ytitle("Biweekly Growth in Cases, World") name(g3, replace)

tsline reproduction_rate if code3=="OWID_WRL"&timevar>21945&timevar<22677, tlabel(21945(120)22677, format(%tdMon_CCYY)) xtitle("") ytitle("Reproduction Rate, World (Smoothed)") name(g4, replace)

graph combine g1 g2 g3 g4, ysize(4) xsize(7)
graph export "figure1.png"

*=============================
* Figure 2 postponement trend
*=============================

sort yy1 mm1
gen timevar_mon = ym(yy1,mm1)
format timevar_mon %tm

egen numElec = count(postponed) if postponed!=., by(yy1 mm1)
egen numPostpone = sum(postponed), by(yy1 mm1)
gen percPostpone = 100*numPostpone/numElec

preserve
	collapse numElec numPostpone percPostpone, by(timevar_mon)
	tsset timevar_mon
	tsline percPostpone if timevar_mon>720&timevar_mon<746, lcolor(black) tlabel(721(3)744, format(%tmMon_CCYY)) ytitle("% Postponement") xtitle("") xsize(9) ysize(3) scale(1.8) scheme(538bw)  graphregion(margin(large)) name(gtrend, replace)
	graph export "figure2.png", replace
restore 

*=============================
* Table 2 results
*=============================

tsset cnum timevar

logit postponed l30.reproduction_rate l30.new_cases_per_million l30.est_excessdeaths_100k, cluster(cnum) 
	estimates store m1
logit postponed l30.i.testing_policy l30.stringency_index hospital_bed, cluster(cnum) 
	estimates store m2
logit postponed regional special byelec, cluster(cnum) 
	estimates store m3
logit postponed polconv, cluster(cnum) 
	estimates store m4
logit postponed l30.reproduction_rate l30.new_cases_per_million l30.est_excessdeaths_100k l30.i.testing_policy l30.stringency_index hospital_bed regional special byelec polconv pop_aged cardiovasc_death_rate diabetes_prevalence lgdp human_development_index cl pr, cluster(cnum)
	estimates store m5

esttab m1 m2 m3 m4 m5, label se scalar("r2_p pseudo R2" "ll Log likelihood") star(* 0.10 ** 0.05 *** 0.01)

*=============================
* Figure 3 coefficient plot
*=============================

coefplot (m1, msymbol(O) mcolor(black) ciopts(lcolor(black))) ///
	(m2, msymbol(Oh) mcolor(black) ciopts(lcolor(black))) ///
	(m3, msymbol(S) mcolor(black) ciopts(lcolor(black))) ///
	(m4, msymbol(Sh) mcolor(black) ciopts(lcolor(black))), bylabel("Models 1-4") ///
	|| (m5, msymbol(O)), bylabel("Model 5 (Pooled model)") ///
	||, xline(0, lpattern(solid)) ci(90) b1title("Logit coefficient", size(medsmall)) ///
	drop(_cons pop_aged cardiovasc_death_rate diabetes_prevalence lgdp human_development_index cl pr) ///
	coeflabels(L30.reproduction_rate = "R-number (lagged)" L30.new_cases_per_million = "New cases (per mil. lagged)" L30.est_excessdeaths_100k="Excess deaths (per mil. lagged)" 0bL30.testing_policy="Testing policy (none)" 1L30.testing_policy="Testing policy (two criteria)" 2L30.testing_policy="Testing policy (w/ symptom)" 3L30.testing_policy="Testing policy (anyone)" L30.stringency_index="Stringency index", labsize(medsmall)) ///
	legend(off) byopts(legend(off) scale(1.3)) xsize(7) ysize(4) scheme(538bw)

graph export "figure3.png", replace

*=============================
*	Table 3 standardized coefs
*=============================

logit postponed l30.reproduction_rate l30.new_cases_per_million  l30.est_excessdeaths_100k l30.i.testing_policy l30.stringency_index hospital_bed regional special byelec polconv pop_aged  cardiovasc_death_rate diabetes_prevalence lgdp human_development_index cl pr, cluster(cnum)

help listcoef			
listcoef, std help // see bStdX  

matrix a = r(table)
matrix b = X[1..20,4]
matrix list b

*=============================
*	Table A1 summary stats
*=============================

*ssc install fsum

fsum postpone national regional byelection special reproduction_rate new_cases_per_million est_excessdeaths_100k testing_policy stringency_index hospital_bed polconv pop_aged cardiovasc_death_rate diabetes_prevalence lgdp human_development_index cl pr if postponed!=., uselabel

*=============================
*	Figure A1 
*=============================

logit postponed l30.reproduction_rate l30.new_cases_per_million  l30.est_excessdeaths_100k l30.i.testing_policy l30.stringency_index hospital_bed regional special byelec polconv pop_aged  cardiovasc_death_rate diabetes_prevalence lgdp human_development_index cl pr, cluster(cnum)
	estimates store m5
logit postponed l30.reproduction_rate l30.new_cases_per_million  l30.est_excessdeaths_100k l30.i.testing_policy l30.stringency_index hospital_bed regional special byelec polconv pop_aged  cardiovasc_death_rate diabetes_prevalence lgdp human_development_index cl pr
	estimates store m5naive
xtlogit postponed l30.reproduction_rate l30.new_cases_per_million  l30.est_excessdeaths_100k l30.i.testing_policy l30.stringency_index hospital_bed regional special byelec polconv pop_aged  cardiovasc_death_rate diabetes_prevalence lgdp human_development_index cl pr
	estimates store m5xt

coefplot m5 m5naive m5xt  ///
	||, xline(0, lcolor(black) lpattern(solid)) ci(90) b1title("Logit coefficient", size(medsmall)) drop(_cons pop_aged cardiovasc_death_rate diabetes_prevalence lgdp human_development_index cl pr)  ///
	legend(order(2 "robust error" 4 "naive" 6 "random effects")) ///
	coeflabels(L30.reproduction_rate = "R-number (lagged)" L30.new_cases_per_million = "New cases (per mil. lagged)" L30.est_excessdeaths_100k="Excess deaths (per mil. lagged)" 0bL30.testing_policy="Testing policy (none)" 1L30.testing_policy="Testing policy (two criteria)" 2L30.testing_policy="Testing policy (w/ symptom)" 3L30.testing_policy="Testing policy (anyone)" L30.stringency_index="Stringency index", labsize(medsmall)) ///
	byopts(legend(off) scale(1.3)) xsize(6) ysize(4) title("Model 5 (Pooled model)") scheme(538bw)

graph export "figureA1.png", replace

*=============================
*	Table A2 
*=============================

* model 1 (H1)
logit postponed l30.reproduction_rate l30.new_cases_per_million l30.est_excessdeaths_100k, cluster(cnum) 
	estimates store m1
logit postponed l20.reproduction_rate l20.new_cases_per_million l20.est_excessdeaths_100k, cluster(cnum) 
	estimates store m1lag20
logit postponed l45.reproduction_rate l45.new_cases_per_million l45.est_excessdeaths_100k, cluster(cnum) 
	estimates store m1lag45
	
* model 2 (H2)
logit postponed l30.i.testing_policy l30.stringency_index hospital_bed, cluster(cnum) 
	estimates store m2
logit postponed l20.i.testing_policy l20.stringency_index hospital_bed, cluster(cnum) 
	estimates store m2lag20
logit postponed l45.i.testing_policy l45.stringency_index hospital_bed, cluster(cnum) 
	estimates store m2lag45
	
* table
esttab m1 m1lag20 m1lag45 m2 m2lag20 m2lag45, label se scalar("r2_p pseudo R2" "ll Log likelihood") star(* 0.10 ** 0.05 *** 0.01)

*=============================
*	Table A3
*=============================

use "repDataElecPostponeExtended.dta", clear

tsset cnum timevar

logit postponed l30.reproduction_rate l30.new_cases_per_million l30.est_excessdeaths_100k, cluster(cnum) 
	estimates store m1ext
logit postponed l30.i.testing_policy l30.stringency_index hospital_bed, cluster(cnum) 
	estimates store m2ext
logit postponed regional special byelec, cluster(cnum) 
	estimates store m3ext
logit postponed polconv, cluster(cnum) 
	estimates store m4ext
logit postponed l30.reproduction_rate l30.new_cases_per_million l30.est_excessdeaths_100k l30.i.testing_policy l30.stringency_index hospital_bed regional special byelec polconv pop_aged cardiovasc_death_rate diabetes_prevalence lgdp human_development_index cl pr, cluster(cnum)
	estimates store m5ext

esttab m1ext m2ext m3ext m4ext m5ext, label se scalar("r2_p pseudo R2" "ll Log likelihood") star(* 0.10 ** 0.05 *** 0.01)	


*\END
